package cn.wizzer.app.sys.modules.services.impl;

import cn.wizzer.app.sys.modules.models.SysMsg;
import cn.wizzer.app.sys.modules.models.SysMsgUser;
import cn.wizzer.app.sys.modules.models.SysUser;
import cn.wizzer.app.sys.modules.services.SysMsgService;
import cn.wizzer.app.sys.modules.services.SysMsgUserService;
import cn.wizzer.app.sys.modules.services.SysUserService;
import cn.wizzer.app.user.modules.models.vo.SysMsgUserVo;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import com.alibaba.dubbo.config.annotation.Service;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;

@IocBean(args = {"refer:dao"})
@Service(interfaceClass = SysMsgService.class)
public class SysMsgServiceImpl extends BaseServiceImpl<SysMsg> implements SysMsgService {
    public SysMsgServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private SysMsgUserService sysMsgUserService;
    @Inject
    private SysUserService sysUserService;

    @Inject
    private CommonDBService dbService;

    public SysMsg saveMsg(SysMsg sysMsg, String[] users) {
        SysMsg dbMsg = this.insert(sysMsg);
        if (Strings.isNotBlank(dbMsg.getUrl())) {
            this.update(Chain.make("url", dbMsg.getUrl() + dbMsg.getId()), Cnd.where("id", "=", dbMsg.getId()));
        }
        if (dbMsg != null) {
            if ("user".equals(dbMsg.getType()) && users != null) {
                for (String loginname : users) {
                    SysMsgUser sys_msgUser = new SysMsgUser();
                    sys_msgUser.setMsgId(dbMsg.getId());
                    sys_msgUser.setStatus(0);
                    sys_msgUser.setLoginname(loginname);
                    sysMsgUserService.insert(sys_msgUser);
                }
            }
            if (("member".equals(dbMsg.getType()) || "agent".equals(dbMsg.getType())) && users != null) {
                for (String userId : users) {
                    SysMsgUser sys_msgUser = new SysMsgUser();
                    sys_msgUser.setMsgId(dbMsg.getId());
                    sys_msgUser.setStatus(0);
                    sys_msgUser.setUserId(userId);
                    sysMsgUserService.insert(sys_msgUser);
                }
            }
            if ("system".equals(dbMsg.getType())) {
                Cnd cnd = Cnd.where("disabled", "=", false).and("delFlag", "=", false);
                int total = sysUserService.count(cnd);
                int size = 1000;
                Pagination pagination = new Pagination();
                pagination.setTotalCount(total);
                pagination.setPageSize(size);
                for (int i = 1; i <= pagination.getTotalPage(); i++) {
                    Pagination pagination2 = sysUserService.listPage(i, size, cnd);
                    for (Object sysUser : pagination2.getList()) {
                        SysUser user = (SysUser) sysUser;
                        SysMsgUser sys_msgUser = new SysMsgUser();
                        sys_msgUser.setMsgId(dbMsg.getId());
                        sys_msgUser.setStatus(0);
                        sys_msgUser.setLoginname(user.getLoginname());
                        sysMsgUserService.insert(sys_msgUser);
                    }
                }
            } else if ("agentAll".equals(dbMsg.getType()) || "memberAll".equals(dbMsg.getType())) {
                //仅插入消息不插入绑定关系，第一行
            }
        }
        sysMsgUserService.clearCache();
        return dbMsg;
    }

    /**
     * 构建消息通知
     *
     * @param type
     * @param title
     * @param note
     * @return
     */
    @Override
    public SysMsg createMsg(String type, String title, String note, String opBy) {
        SysMsg msg = new SysMsg();
        //所有管理员
        msg.setType(type);
        msg.setTitle(title);
        msg.setNote(note);
        msg.setUrl("/platform/sys/msg/user/all/detail/");
        msg.setSendAt(Times.getTS());
        msg.setOpBy(opBy);
        return msg;
    }

    public void deleteMsg(String id) {
        this.vDelete(id);
        sysMsgUserService.vDelete(Cnd.where("msgId", "=", id));
        sysMsgUserService.clearCache();
    }

    public Pagination listPage(int pageNumber, int pageSize, String msgType, String userId) {
        Sql sql = Sqls.create("select sm.*, smu.status from sys_msg sm ");
        Sql countSql = Sqls.create("select count(1) from sys_msg sm ");
        Sql joinSql = Sqls.create("left join sys_msg_user smu on sm.id = smu.msgId and smu.userId = @userId " +
                "$condition ");
        Cnd cnd = Cnd.where("sm.delFlag", "=", 0)
                .and("sm.type", "=", msgType);
        if(!msgType.equals("memberAll")){
            cnd.and("smu.delFlag", "=", 0);
        }
        joinSql.setParam("userId", userId);
        joinSql.setCondition(cnd);
        sql.appendSourceSql(joinSql.toString());
        countSql.appendSourceSql(joinSql.toString());
        sql.appendSourceSql("order by opAt desc");
        return dbService.listPage(SysMsgUserVo.class, pageNumber, pageSize, sql.toString(), countSql.toString());
    }

    @Override
    public Pagination listPage(Integer pageNumber, Integer pageSize, String status, String loginName, String type) {
        Cnd cnd = Cnd.NEW();
        if (Strings.isNotBlank(status) && "read".equals(status)) {
            cnd.and("a.status", "=", 1);
        }
        if (Strings.isNotBlank(status) && "unread".equals(status)) {
            cnd.and("a.status", "=", 0);
        }
        cnd.and("a.loginname", "=", loginName);
        cnd.and("a.delFlag", "=", false);
        cnd.desc("a.opAt");
        if (Strings.isNotBlank(type) && !"all".equals(type)) {
            cnd.and("b.type", "=", type);
        }
        Sql sql = Sqls.create("SELECT b.type,b.title,b.sendAt,a.* FROM sys_msg b LEFT JOIN sys_msg_user a ON b.id=a.msgId $condition ");
        sql.setCondition(cnd);
        Sql sqlCount = Sqls.create("SELECT count(*) FROM sys_msg b LEFT JOIN sys_msg_user a ON b.id=a.msgId $condition ");
        sqlCount.setCondition(cnd);
        return dbService.listPage(cn.wizzer.app.sys.modules.models.vo.SysMsgUserVo.class, pageNumber, pageSize, sql.toString(), sqlCount.toString());
    }
}
